// slice允许你引用集合中一段连续的元素序列,而不用引用整个集合.
// slice是一种引用,没有所有权
pub fn learn_slice() {
  _learn_slice0();
  _learn_slice1();
}

fn first_word0(s: &String) -> usize {
  let bytes = s.as_bytes();
  for (i, &item) in bytes.iter().enumerate() {
    if item == b' ' {
      return i;
    }
  }

  s.len()
}

fn _learn_slice0() {
  let mut s = String::from("hello world");
  let i = first_word0(&s);
  s.clear();
  println!("{s}, {i}");
  // i 与 s同步的问题. 因为i仅在s不变的情况下有效,s发生变化后,i所指向的字符可能就变了或者不存在了.
  // 这是一个潜在的bug.
}

// 返回一个字符串slice
fn first_word1(s: &String) -> &str {
  let bytes = s.as_bytes();
  for (i, &item) in bytes.iter().enumerate() {
    if item == b' ' {
      return &s[..i];
    }
  }

  &s[..]
}

fn _learn_slice1() {
  let mut s = String::from("hello world");
  let hello = &s[0..5]; // hello是部分s的引用,胖指针
  let world = &s[6..11]; // world也是部分s的引用
  println!("{s}, {hello}, {world}");

  let s1 = first_word1(&s);
  println!("{s1}");

  &s.clear();
  //println!("{s1}"); // 编译错误, _learn_slice0()那样的用法有隐患,改用slice就让编译器暴露了这个问题

  let a = [1, 2, 3, 4, 5];
  let slice = &a[..3];
  println!("{:?}", slice);
}
